package ee.az.test.wave;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author Artur Zinatullin (artur.zinatullin@gmail.com) 2011
 */
public class Field {

	private final int width, height;
	private Cell[][] field;
	private boolean valid;

	public Field(int width, int height) {
		this.width = width;
		this.height = height;

		field = new Cell[width][height];
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < width; y++) {
				field[x][y] = new Cell();
			}
		}
	}

	public Cell getCell(int x, int y) {
		if (x >= 0 && x < width && y >= 0 && y < height) {
			return field[x][y];
		} else {
			return null;
		}
	}

	public List<Cell> getNeighbours(int x, int y) {
		List<Cell> result = new ArrayList<Cell>(8);
		addNotNull(getCell(x-1, y-1), result);
		addNotNull(getCell(x-1, y), result);
		addNotNull(getCell(x-1, y+1), result);
		addNotNull(getCell(x, y-1), result);
		addNotNull(getCell(x, y+1), result);
		addNotNull(getCell(x+1, y-1), result);
		addNotNull(getCell(x+1, y), result);
		addNotNull(getCell(x+1, y+1), result);
		return result;
	}

	private void addNotNull(Cell cell, Collection<Cell> collection) {
		if (cell != null) {
			collection.add(cell);
		}
	}

	public void tick() {
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < width; y++) {
				Cell currentCell = getCell(x, y);
				List<Cell> currentNeighbours = getNeighbours(x, y);
				for (Cell neighbour : currentNeighbours) {
					double dv = (neighbour.getHeight() - currentCell.getHeight()) * 0.01;
					currentCell.setSpeed(currentCell.getSpeed() + dv);
					// TODO add friction
					//dv = (neighbour.getSpeed() - currentCell.getSpeed()) * 0.01;
					//currentCell.setSpeed(currentCell.getSpeed() +  dv);
				}
			}
		}
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < width; y++) {
				Cell currentCell = getCell(x, y);
				currentCell.setHeight(currentCell.getHeight() + currentCell.getSpeed() * 1);
				List<Cell> currentNeighbours = getNeighbours(x, y);
				double dh = 0;
				for (Cell neighbour : currentNeighbours) {
					double dnh = (neighbour.getHeight() - currentCell.getHeight()) * 0.01;
					dh =+ dnh;
					neighbour.setHeight(neighbour.getHeight() - dnh);
				}
				currentCell.setHeight(currentCell.getHeight() + dh);
			}
		}
		valid = false;
	}

	public void validate() {
		valid = true;
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public boolean isValid() {
		return valid;
	}
}
